﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using MTGenome.MTG;

namespace MTGenome.Gatherer
{
    /// <summary>
    /// TODO: notify index out of range to end game
    /// </summary>
    [Export(typeof(ILibrary)), PartCreationPolicy(CreationPolicy.NonShared)]
    public sealed class Library : ILibrary
    {
        //Index 0 is the top, _cards.Length - 1 is the bottom
        private List<ICard> _cards = new List<ICard>();
        private Random _rand = new Random(Environment.TickCount);

        public ICard Draw()
        {
            var item = _cards[0];
            _cards.RemoveAt(0);
            return item;
        }

        public ICard DrawFromBottom()
        {
            int index = _cards.Count - 1;
            var item = _cards[index];
            _cards.RemoveAt(index);
            return item;
        }

        public IEnumerable<ICard> DrawX(int X)
        {
            for (int i = 0; i < X; i++)
            {
                yield return _cards[i];
            }
            _cards.RemoveRange(0, X);
            yield break;
        }

        public IEnumerable<ICard> DrawXFromBotton(int X)
        {
            for (int i = 0; i < X; i++)
            {
                yield return _cards[_cards.Count - i - 1];
            }
            _cards.RemoveRange(_cards.Count - X, X);
            yield break;
        }

        public ICard ViewTop()
        {
            return _cards[0];
        }

        public ICard ViewBottom()
        {
            return _cards[_cards.Count - 1];
        }

        public IEnumerable<ICard> ViewTopX(int X)
        {
            for (int i = 0; i < X; i++)
            {
                yield return _cards[i];
            }
        }

        public IEnumerable<ICard> ViewBottomX(int X)
        {
            for (int i = 0; i < X; i++)
            {
                yield return _cards[_cards.Count - i - 1];
            }
        }

        public IEnumerable<ICard> ViewAll()
        {
            return _cards;
        }

        public void PlaceOnTop(ICard card)
        {
            _cards.Insert(0, card);
        }

        public void PlaceOnBotton(ICard card)
        {
            _cards.Add(card);
        }

        public void Shuffle()
        {
            List<ICard> shuffled = new List<ICard>(_cards.Count);

            while (_cards.Count > 0)
            {
                int index = _rand.Next(0, _cards.Count);
                shuffled.Add(_cards[index]);
                _cards.RemoveAt(index);
            }

            _cards = shuffled;
        }

        public void Load(IEnumerable<ICard> cards)
        {
            _cards = cards.ToList();
        }


        public int CardCount
        {
            get { return _cards.Count; }
        }
    }
}
